package com.takwolf.libgdx.core;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;

public final class Viewport {

    private static final int P_320 = 320;   // x2 -> 160px
    private static final int P_480 = 480;   // x3 -> 160px
    private static final int P_640 = 640;   // x4 -> 160px
    private static final int P_720 = 720;   // x4 -> 180px
    private static final int P_1080 = 1080; // x6 -> 180px
    private static final int P_1280 = 1280; // x8 -> 160px
    private static final int P_1440 = 1440; // x8 -> 180px

    private int zoom;    // 视口放大比例，相当于显示像素x倍数
    private float width;
    private float height;
    private OrthographicCamera camera;

    public Viewport() {
        camera = new OrthographicCamera();
        resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    }

    protected void resize(int screenWidth, int screenHeight) {
        if (screenHeight >= P_1440) {
            zoom = 8;
        }
        else if (screenHeight >= P_1280) {
            zoom = 8;
        }
        else if (screenHeight >= P_1080) {
            zoom = 6;
        }
        else if (screenHeight >= P_720) {
            zoom = 4;
        }
        else if (screenHeight >= P_640) {
            zoom = 4;
        }
        else if (screenHeight >= P_480) {
            zoom = 3;
        }
        else if (screenHeight >= P_320) {
            zoom = 2;
        }
        else {
            zoom = 1;
        }
        width = screenWidth / (float) zoom;
        height = screenHeight / (float) zoom;
        camera.setToOrtho(false, width, height);
    }

    public float getX() {
        return camera.position.x - width / 2.0f;
    }

    public float getY() {
        return camera.position.y - height / 2.0f;
    }

    public float getWidth() {
        return width;
    }

    public float getHeight() {
        return height;
    }

    public Rectangle getRectangle() {
        return new Rectangle(getX(), getY(), width, height);
    }

    public int getZoom() {
        return zoom;
    }

    public OrthographicCamera getCamera() {
        return camera;
    }

    public Vector3 getCameraTarget() {
        return camera.position;
    }

    public float getCameraTargetX() {
        return camera.position.x;
    }

    public float getCameraTargetY() {
        return camera.position.y;
    }

    public void setCameraTarget(Batch batch, float targetX, float targetY) {
        camera.position.set(targetX, targetY, 0);
        camera.update();
        batch.setProjectionMatrix(camera.combined);
    }

    public void setCameraTargetToScreenCenter(Batch batch) {
        setCameraTarget(batch, width / 2.0f, height / 2.0f);
    }

    public void pushScissors(Batch batch, Rectangle area) {
        Rectangle scissors = new Rectangle();
        ScissorStack.calculateScissors(camera, batch.getTransformMatrix(), area, scissors);
        ScissorStack.pushScissors(scissors);
    }

    public void popScissors(Batch batch) {
        batch.flush();
        ScissorStack.popScissors();
    }

    public void pushViewportScissors(Batch batch) {
        pushScissors(batch, getRectangle());
    }

}
